package handler

import (
	"bytes"
	"encoding/json"
	"fmt"
	"log"
	"time"

	"github.com/dahuamao/task-scheduler/config"
	"github.com/dahuamao/task-scheduler/model"

	"net/http"

	"github.com/gin-gonic/gin"
	"gorm.io/datatypes"
)

type TaskStatus string

// 2. 使用 iota 定义枚举值（从 0 开始自动递增）
const (
	StatusPending   TaskStatus = "PENDING"   // 待执行
	StatusRunning   TaskStatus = "RUNNING"   // 执行中
	StatusCompleted TaskStatus = "COMPLETED" // 已完成
	StatusFailed    TaskStatus = "FAILED"    // 失败
)

// CreateTaskRequest 创建任务的请求体结构
type CreateTaskRequest struct {
	Biz    string `json:"biz" binding:"required"`
	Title  string `json:"title" binding:"required"`
	Desc   string `json:"desc" binding:"required"`
	UserId string `json:"user_id" binding:"required"`
	Count  int    `json:"count"`
	Cb     string `json:"cb"`
}

// CreateTask 处理创建任务的POST请求
func CreateTask(c *gin.Context) {
	var req CreateTaskRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(400, gin.H{"error": err.Error()})
		return
	}

	// 创建新任务
	task := model.Task{
		Biz:        req.Biz,
		Title:      req.Title,
		Desc:       req.Desc,
		UserId:     req.UserId,
		CreateTime: time.Now(),
		UpdateTime: time.Now(),
		Status:     string(StatusPending), // 初始状态为待执行
		Cb:         req.Cb,
		Result:     datatypes.JSON("{}"),
	}

	// GORM操作是同步的，会阻塞直到数据库操作完成
	if err := config.DB.Create(&task).Error; err != nil {
		c.JSON(500, gin.H{"error": "创建任务失败: " + err.Error()})
		return
	}

	c.JSON(201, gin.H{
		"message": "任务创建成功",
		"task":    task,
	})
}

// ListTasks 获取任务列表（支持分页）
func ListTasks(c *gin.Context) {
	params := GetPaginationParams(c)
	var tasks []model.Task

	// 从header中获取user_id参数（必传）
	userID := c.GetHeader("user_id")
	if userID == "" {
		c.JSON(400, gin.H{"error": "user_id header is required"})
		return
	}

	// 构建查询
	query := config.DB.Model(&model.Task{})

	// 添加user_id过滤条件
	query = query.Where("user_id = ?", userID)

	response, err := PaginateQueryWithOrder(query, params, "create_time DESC", &tasks)
	if err != nil {
		c.JSON(500, gin.H{"error": "获取任务列表失败: " + err.Error()})
		return
	}

	response.Data = gin.H{"tasks": tasks}
	c.JSON(200, response)
}

// GetTask 获取单个任务详情
func GetTask(c *gin.Context) {
	var task model.Task
	id := c.Param("id")

	if err := config.DB.First(&task, id).Error; err != nil {
		c.JSON(404, gin.H{"error": "任务不存在"})
		return
	}

	c.JSON(200, task)
}

// UpdateTask 更新任务信息
func UpdateTask(c *gin.Context) {
	var task model.Task
	id := c.Param("id")

	if err := config.DB.First(&task, id).Error; err != nil {
		c.JSON(404, gin.H{"error": "任务不存在"})
		return
	}

	var req CreateTaskRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(400, gin.H{"error": err.Error()})
		return
	}

	// 更新任务信息
	task.Title = req.Title
	task.Desc = req.Desc
	task.UpdateTime = time.Now()
	if err := config.DB.Save(&task).Error; err != nil {
		c.JSON(500, gin.H{"error": "更新任务失败: " + err.Error()})
		return
	}

	c.JSON(200, gin.H{
		"message": "任务更新成功",
		"task":    task,
	})
}

// DeleteTask 删除任务
func DeleteTask(c *gin.Context) {
	id := c.Param("id")

	if err := config.DB.Delete(&model.Task{}, id).Error; err != nil {
		c.JSON(500, gin.H{"error": "删除任务失败: " + err.Error()})
		return
	}

	c.JSON(200, gin.H{"message": "任务删除成功"})
}

// 处理客户端返回的任务结果
func HandleTaskResult(taskID int, jsonResult string, success bool) error {
	// 更新任务状态和结果
	var task model.Task
	if err := config.DB.First(&task, taskID).Error; err != nil {
		return fmt.Errorf("获取任务信息失败: %v", err)
	}
	tx := config.DB.Model(&model.Task{}).Where("id = ?", taskID)
	if success {
		tx.Update("status", StatusCompleted)
	} else {
		tx.Update("status", StatusFailed)
	}
	log.Printf("准备调用TaskCallBack，taskID=%d", taskID)
	if err := TaskCallBack(task, jsonResult); err != nil {
		log.Printf("回调失败: %v", err)
	}
	// 将字符串转换为JSON类型
	return tx.Update("result", datatypes.JSON(jsonResult)).Error
}

// 查询未执行的任务
func GetPendingTasks() ([]model.Task, error) {
	var tasks []model.Task

	// 查询状态为pending
	result := config.DB.Where("status = ?",
		string(StatusPending)).Find(&tasks)

	return tasks, result.Error
}

// callback
func TaskCallBack(task model.Task, result string) error {
	// 当存在回调URL时，发送POST请求
	if task.Cb != "" {
		// 创建请求体
		jsonBody, err := json.Marshal(result)
		if err != nil {
			return fmt.Errorf("序列化结果失败: %v", err)
		}

		// 发送POST请求
		resp, err := http.Post(task.Cb, "application/json", bytes.NewBuffer(jsonBody))
		if err != nil {
			return fmt.Errorf("发送回调请求失败: %v", err)
		}
		defer resp.Body.Close()

		// 检查响应状态
		if resp.StatusCode < 200 || resp.StatusCode >= 300 {
			return fmt.Errorf("回调请求失败，状态码: %d", resp.StatusCode)
		}
	}
	return nil
}
